from flask import Flask, request, jsonify

import smtplib
from email.mime.text import MIMEText
from email.header import Header

from jsonschema import validate

import settings
from model_log import Log

from flask_celeryext import create_celery_app

from mongoengine import connect
from datetime import datetime

app = Flask(__name__)
app.config.update(dict(
    CELERY_BROKER_URL='redis://127.0.0.1:6379/1',
    CELERY_RESULT_BACKEND='redis://127.0.0.1:6379/2'))
celery = create_celery_app(app)

connect(host=settings.mongo_host)


@app.errorhandler(500)
def handle_500(e):
    print(e)
    return jsonify(msg="500 Internal Server Error！")


@celery.task(name='send_mail')
def send_mail(receivers, subject, mainbody):
    mainbody = mainbody + "\n\n\n----------------------------------\n该邮件为系统发送，请勿回复！"

    message = MIMEText(mainbody, 'plain')  # 正文
    message['From'] = Header(settings.message_From)  # 发件人
    message['To'] = ','.join(receivers)  # 收件人
    message['Subject'] = Header(subject)

    smtpObj = smtplib.SMTP_SSL(settings.mail_host, 465)
    smtpObj.login(settings.mail_user, settings.mail_pass)
    smtpObj.sendmail(settings.sender, receivers, message.as_string())


@app.route('/', methods=["GET", "POST"])
def receive_json():
    if request.method == "GET":
        return "<h1>Mail_Server Started!!</h1>"
    schema = {
        "type": "object",
        "required": ["receivers", "subject", "mainbody"],
        "properties": {
            "receivers": {"type": "array", "items": {"type": "string"}, "minItems": 1,
                          "uniqueItems": True},
            "subject": {"type": "string", "minLength": 4},
            "mainbody": {"type": "string", "minLength": 4}
        },
    }
    # noinspection PyBroadException
    try:
        validate(instance=request.json, schema=schema)
    except Exception:
        return jsonify(msg="Object of type ValidationError is not JSON serializable")

    receivers = request.json.get("receivers")  # 接收邮件,list
    subject = request.json.get("subject")  # 主题
    mainbody = request.json.get("mainbody")  # 正文

    mail_log = Log(receivers=receivers, subject=subject, mainbody=mainbody, create_date=datetime.now())
    mail_log.save()  # 存日志

    send_mail.delay(receivers, subject, mainbody)  # 异步发送邮件
    # send_mail(receivers, subject, mainbody) # 同步发送邮件
    return jsonify(msg="succeed！")

# TODO 注意事项
# ubuntu 发送邮件需安装
# sudo apt-get install sendmail
# sudo apt-get install sendmail-cf
# sudo apt-get install mailutils
# sudo apt-get install sharutils
# 检查 ps aux | grep sendmail

# 同一台机器启动多个celery，broker_url必须不同
# 启动celery：pipenv run celery -A app.celery worker -l info -P eventlet

# redis中date_done时区问题，找到celery包中backends文件下的base中文件，设置date_done，从datetime.utcnow()修改为datetime.now()
